package com.orm_plus;

import com.orm.executor.DefaultExecutor;
import com.spring.transaction.TransactionSynchronizationManager;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.*;

/**
 * 执行器  orm plus 的执行器，继承orm 的默认执行器，重写2个方法
 * 打开连接，和清理资源的2个方法，其他方法直接继承即可
 */
@Slf4j
public class SimpleExecutor extends DefaultExecutor {
	
	public SimpleExecutor(DataSource dataSource) {
		super(dataSource);
	}
	
	
	// 重写父类方法，获取连接从 数据源获取
	@Override
	public Connection getConnection() throws SQLException {
		Connection conn = TransactionSynchronizationManager.getResource();
		if (conn == null) {
			conn = dataSource.getConnection();
		}
		return conn;
	}
	
	// 重写父类方法，关闭资源 ，关闭连接时判断下
	@Override
	public void close(Connection conn, PreparedStatement ps, ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException exception) {
				exception.printStackTrace();
			}
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException exception) {
				exception.printStackTrace();
			}
		}
		if (conn != null) {
			// 连接是否关闭，要看连接是自己打开的，还是 spring 打开的
			if (TransactionSynchronizationManager.getResource() == null) {
				try {
					conn.close();
				} catch (SQLException exception) {
					exception.printStackTrace();
				}
			}
		}
	}
	
	//
	// public int selectCount(MapperStatement mapperStatement, Object... args) {
	// 	int resultCount = 0;  //结果数
	// 	Connection conn = null;
	// 	PreparedStatement ps = null;
	// 	ResultSet rs = null;
	//
	// 	try {
	// 		conn = getConnection();
	// 		String parseSql = ParameterHandler.parseOgnl(mapperStatement.getSql());
	// 		ps = conn.prepareStatement(parseSql);
	// 		ParameterHandler.setParameters(ps, args);
	// 		rs = ps.executeQuery();
	// 		rs.next();
	// 		resultCount = rs.getInt(1);
	// 		return resultCount;
	// 	} catch (SQLException exception) {
	// 		log.error(exception.getMessage());
	// 		throw new RuntimeException("发生SQL异常");
	// 	} finally {
	// 		close(conn, ps, rs);
	// 	}
	// }
	//
	//
	// public Object selectOne(MapperStatement mapperStatement, Object[] args) {
	// 	int resultCount = 0;  //结果数
	// 	Connection conn = null;
	// 	PreparedStatement ps = null;
	// 	ResultSet rs = null;
	//
	// 	Object obj = null;
	// 	try {
	// 		conn = getConnection();
	// 		String parseSql = ParameterHandler.parseOgnl(mapperStatement.getSql());
	// 		ps = conn.prepareStatement(parseSql);
	// 		ParameterHandler.setParameters(ps, args);
	// 		rs = ps.executeQuery();
	//
	// 		ResultSetMetaData rsmd = rs.getMetaData();
	// 		int columnCount = rsmd.getColumnCount();
	//
	// 		while (rs.next()) {
	// 			Class<?> clazz = ClassUtil.loadClass(mapperStatement.getReturnType());
	// 			obj = parseResultSet(rs, rsmd, clazz);
	//
	// 			resultCount++;
	// 			if (resultCount > 1) {
	// 				log.error("返回结果超过1条");
	// 				return null;
	// 			}
	// 		}
	// 		return obj;
	// 	} catch (SQLException exception) {
	// 		log.error(exception.getMessage());
	// 		throw new RuntimeException("发生SQL异常");
	// 	} finally {
	// 		close(conn, ps, rs);
	// 	}
	// }
	//
	//
	// public List<Object> selectList(MapperStatement mapperStatement, Object[] args) {
	// 	String returnType = mapperStatement.getReturnType();
	// 	String elementType = ClassUtil.getReturnTypeString(returnType);
	// 	Class<?> clazz = ClassUtil.loadClass(elementType);
	//
	// 	ArrayList<Object> resultList = new ArrayList<>();
	//
	// 	Connection conn = null;
	// 	PreparedStatement ps = null;
	// 	ResultSet rs = null;
	//
	// 	try {
	// 		conn = getConnection();
	// 		String parseSql = ParameterHandler.parseOgnl(mapperStatement.getSql());
	// 		ps = conn.prepareStatement(parseSql);
	// 		ParameterHandler.setParameters(ps, args);
	// 		rs = ps.executeQuery();
	//
	// 		ResultSetMetaData rsmd = rs.getMetaData();
	//
	// 		while (rs.next()) {
	// 			Object obj = parseResultSet(rs, rsmd, clazz);
	// 			resultList.add(obj);
	// 		}
	// 		return resultList;
	// 	} catch (SQLException exception) {
	// 		log.error(exception.getMessage());
	// 		throw new RuntimeException("发生SQL异常");
	// 	} finally {
	// 		close(conn, ps, rs);
	// 	}
	// }
	//
	//
	// // insert 独立出来，返回插入的主键
	// public int insert(MapperStatement mapperStatement, Object[] args) {
	// 	Connection conn = null;
	// 	PreparedStatement ps = null;
	// 	ResultSet rs = null;
	//
	// 	try {
	// 		conn = getConnection();
	// 		String parseSql = ParameterHandler.parseOgnl(mapperStatement.getSql());
	// 		ps = conn.prepareStatement(parseSql, Statement.RETURN_GENERATED_KEYS);
	//
	// 		ParameterHandler.setParameters(ps, args);
	// 		ps.executeUpdate();
	//
	// 		rs = ps.getGeneratedKeys();
	//
	// 		if (rs.next()) {
	// 			Long keyId = rs.getLong(1);
	// 			return keyId.intValue();
	// 		}
	// 		return 0;
	// 	} catch (SQLException exception) {
	// 		log.error(exception.getMessage());
	// 		throw new RuntimeException("发生SQL异常");
	// 	} finally {
	// 		close(conn, ps, rs);
	// 	}
	//
	// }
	//
	//
	// public int update(MapperStatement mapperStatement, Object[] args) {
	// 	int effectRows = 0;  //影响行数
	// 	Connection conn = null;
	// 	PreparedStatement ps = null;
	// 	ResultSet rs = null;
	//
	// 	try {
	// 		conn = getConnection();
	// 		String parseSql = ParameterHandler.parseOgnl(mapperStatement.getSql());
	// 		ps = conn.prepareStatement(parseSql);
	//
	//
	// 		ParameterHandler.setParameters(ps, args);
	// 		effectRows = ps.executeUpdate();
	// 		return effectRows;
	// 	} catch (SQLException exception) {
	// 		log.error(exception.getMessage());
	// 		throw new RuntimeException("发生SQL异常");
	// 	} finally {
	// 		close(conn, ps, rs);
	// 	}
	//
	// }
	//
	// /**
	//  * 明天改写这个类 ，利用下  handler 里面的一堆类型处理器
	//  *
	//  * @param rs
	//  * @param rsmd
	//  * @param clazz
	//  * @param <T>
	//  * @return
	//  * @throws RuntimeException
	//  */
	// private <T> T parseResultSet(ResultSet rs, ResultSetMetaData rsmd, Class<T> clazz) throws RuntimeException {
	// 	try {
	// 		T obj = clazz.newInstance();
	// 		int columnCount = rsmd.getColumnCount();
	//
	// 		for (int i = 1; i <= columnCount; i++) {
	// 			// String columnName = rsmd.getColumnName(i);              // 列名，列序号从1开始 ,  bug 修正:这个是原始的表列名，无法取得 sql 中的别名
	// 			String columnName = rsmd.getColumnLabel(i);
	//
	//
	// 			String columnClassName = rsmd.getColumnClassName(i);    // 数据列 类名
	//
	//
	// 			Field field = clazz.getDeclaredField(columnName);
	// 			String fieldClassName = field.getType().getName();
	//
	// 			String setMethodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
	// 			Method method = null;
	// 			Object val = null;
	//
	//
	// 			// 干，神经病 java.sql.Date   傻逼类型
	//
	// 			if (columnClassName.equals(fieldClassName)) {
	//
	// 				method = clazz.getMethod(setMethodName, ClassUtil.loadClass(columnClassName));
	// 				val = rs.getObject(i);
	// 			} else {
	// 				TypeHandler handler = TypeHandlerManager.getHandler(columnClassName, fieldClassName);
	// 				if (handler != null) {
	// 					val = handler.apply(rs.getObject(i));
	// 				}
	// 				method = clazz.getMethod(setMethodName, ClassUtil.loadClass(fieldClassName));
	// 			}
	// 			method.invoke(obj, val);
	// 		}
	// 		return obj;
	// 	} catch (SQLException exception) {
	// 		log.error("sql 语句发生问题");
	// 		throw new RuntimeException("sql 语句发生问题");
	// 	} catch (InstantiationException e) {
	// 		log.error("实例化类 {} 时失败", clazz);
	// 		throw new RuntimeException("实例化类时失败");
	// 	} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
	// 		log.error("反射时出现问题:调用异常,方法不存在,私有方法等 ,发生错误的类：{}  错误原因:{}", clazz.getName(), e.getMessage());
	// 		throw new RuntimeException("反射时出现问题");
	// 	} catch (NoSuchFieldException e) {
	// 		log.error("没有这个字段");
	// 		throw new RuntimeException("反射时出现问题");
	// 	}
	// }
	//
	//
	// protected  <T> T parseResultSet2(ResultSet rs, ResultSetMetaData rsmd, Class<T> clazz) throws RuntimeException {
	// 	try {
	// 		T obj = clazz.newInstance();
	// 		int columnCount = rsmd.getColumnCount();
	//
	//
	// 		Field[] fields = clazz.getDeclaredFields();
	// 		for (Field field : fields) {
	//
	// 			String propertyName = field.getName();
	//
	// 			Class<?> type = field.getType();
	//
	// 			com.orm.handler.TypeHandler<?> typeHandler = register.getTypeHandler(type);
	//
	// 			if (typeHandler == null) {
	// 				continue;     // 应该抛异常么？
	// 			}
	// 			Object result = typeHandler.getResult(rs, propertyName);
	// 			field.set(obj, result);
	// 		}
	// 		return obj;
	// 	} catch (SQLException e) {
	// 		log.error("sql 语句发生问题");
	// 		throw new RuntimeException("sql 语句发生问题");
	// 	} catch (InstantiationException | IllegalAccessException exception) {
	// 		log.error("实例化类 {} 时失败", clazz);
	// 		throw new RuntimeException("实例化类时失败");
	// 	}
	// }
}
